// system.h 
//	All global variables used in Nachos are defined here.
//
// Copyright (c) 1992-1993 The Regents of the University of California.
// All rights reserved.  See copyright.h for copyright notice and limitation 
// of liability and disclaimer of warranty provisions.

#ifndef SYSTEM_H
#define SYSTEM_H

#include <time.h>
#include "copyright.h"
#include "utility.h"
#include "thread.h"
#include "scheduler.h"
#include "interrupt.h"
#include "stats.h"
#include "timer.h"
#include "machine.h"
#include "../userprog/bitmap.h"
#include "../userprog/ProcessTable.h"
#include "../vm/IPEntry.h"

#define MAX_PROCESS 512

#include "synch.h"

// Initialization and cleanup routines
extern void Initialize(int argc, char **argv); 	// Initialization,
						// called before anything else
extern void Cleanup();				// Cleanup, called when
						// Nachos is done.

extern Thread *currentThread;			// the thread holding the CPU
extern Thread *threadToBeDestroyed;  		// the thread that just finished
extern Scheduler *scheduler;			// the ready list
extern Interrupt *interrupt;			// interrupt status
extern Statistics *stats;			// performance metrics
extern Timer *timer;				// the hardware alarm clock
extern ProcessTable *processTable;
extern int mailboxId;
extern IPEntry *IPT;
extern int currentTLB;

extern BitMap *swapBmp;
extern OpenFile *swapFile;
extern int pEvict;

extern int *toBeDeletedQueue;//[NumPhysPages];	/*holds the list of pages to be evicted next (when using fifo policy)*/
extern int tbdQSize;

extern int mailboxNumCounter;
extern Lock *mailboxNumCounterLock;

/*
=======================================================================================================================
=======================================================================================================================
*/

class AddrSpace;

const int MAX_LOCKS = 512;
const int MAX_CVS = 512;
const int MAX_MVS = 512;

struct KernelLock{
	Lock *lock;
	AddrSpace *addrSpace; 
	bool isDeleted;
	bool isToBeDeleted;
};


struct Owner {
  int ownerID;
  int mailboxNumber;
};

struct ServerLock{
  char *name;
  bool available;
  Owner owner;
  List *queue;
  int queueSize;
  bool isDeleted;
  bool isToBeDeleted;
};

struct ServerCV {
  char *name;
  List *queue;
  int queueSize;
  ServerLock *lock;
  bool isDeleted;
  bool isToBeDeleted;
};

struct ServerMV {
  char *name;
  int *values[];
  int size;
  bool isDeleted;
  bool isToBeDeleted;
};

struct KernelCV{
	Condition *cond;
	AddrSpace *addrSpace;
	bool isDeleted;
	bool isToBeDeleted;
};


struct KernelMV {
  int values[100];
  int size;
  AddrSpace *addrSpace;
  bool isDeleted;
  bool isToBeDeleted;
};

struct CSPacket {
	int syscallNum;
	char* name;
};

extern int numberOfServers;
extern int myMachID;

extern BitMap *freeKernelLockBmp;
extern BitMap *freeKernelCVBmp;
extern BitMap *freeKernelMVBmp;

#ifdef NETWORK
	extern char* networkLocks[MAX_PROCESS][MAX_LOCKS];
	extern char* networkConditions[MAX_PROCESS][MAX_LOCKS];
	extern char* networkMonitors[MAX_PROCESS][MAX_LOCKS];
#endif

extern KernelLock *kernelLocks[MAX_PROCESS][MAX_LOCKS];		/* the table of locks */
extern KernelCV *kernelConditions[MAX_PROCESS][MAX_CVS];	/* the table of conditions */
extern KernelMV *kernelMonitors[MAX_PROCESS][MAX_MVS];          /* the table of monitors */
extern Lock *kernelLockTableLock; 				/* Lock for the KernelLockTable */
extern Lock *kernelConditionTableLock;				/* Lock for KernelConditionTable */
extern Lock *kernelMonitorTableLock;                            /* Lock for the KernelMonitorTable */
extern int nextLockLocation; 					/* the location of the next lock = the same */
extern int nextConditionLocation;				/* the location of the next condition variable */

extern Lock *iptLock;
extern int nextMonitorLocation;                                 /* the location of the next monitor variable */
extern Lock *pageTableLock;
extern Lock *mbmLock;




/*
=======================================================================================================================
=======================================================================================================================
*/

#ifdef USER_PROGRAM
#include "machine.h"

extern Machine* machine;	// user program memory and registers
extern BitMap *PhysicalMemoryMap;		//the bitmap that to keep track of available memory

#endif

#ifdef FILESYS_NEEDED 		// FILESYS or FILESYS_STUB 
#include "filesys.h"
extern FileSystem  *fileSystem;
#endif

#ifdef FILESYS
#include "synchdisk.h"
extern SynchDisk   *synchDisk;
#endif

#ifdef NETWORK
#include "post.h"
extern PostOffice* postOffice;
#endif

#endif // SYSTEM_H
